package command

import (
	"context"

	"gitee.com/crack007/goose/gsconfig"
	"gitee.com/crack007/goose/gscore"
	"gitee.com/crack007/goose/gslog"
)

type Cmd struct {
	Builder *CmdBuilder
	handle  ICmdHandle
	gscore.BaseServer
	graceful bool
}

func (x *Cmd) OnBeforeInit() {
	x.handle.OnInjectServer(x)
	x.handle.OnBeforeInit()
}

func (x *Cmd) OnInitConfig() {
	var err error
	defer func() {
		if err != nil {
			panic("OnInitConfig err: " + err.Error())
		}
	}()

	if x.Builder.GetConfigPath() != "" {
		gsconfig.ParseConfig(x.Builder.GetConfigPath(), x.Builder.ConfigObject)
		if v, ok := x.Builder.ConfigObject.(gscore.AppConfig); ok {
			if v.Log != nil {
				gslog.DefaultLog = gslog.NewConsoleLogger(v.Log)
			}
		}
	}

	if x.Builder.GetLogDebug() {
		gslog.DefaultLog.SetLogLevel(gslog.LEVEL_DEBUG)
	}

	if x.Builder.GetLogTrace() {
		gslog.DefaultLog.SetLogLevel(gslog.LEVEL_TRACE)
	}

	x.handle.OnInitConfig()
}

func (x *Cmd) OnInitInject() {

}

func (x *Cmd) OnInitService() {
	x.handle.OnInitService()
}

func (x *Cmd) OnInitRouter() {

}

func (x *Cmd) GetBuilder() gscore.IBuilder {
	return x.Builder
}

func (x *Cmd) OnBeforeRun() {
	x.handle.OnBeforeRun()
}

func (x *Cmd) OnBuild() {

}

func (x *Cmd) OnRun() {
	if !x.graceful {
		err := x.handle.OnRun()
		if err != nil {
			panic(err)
		}
		x.handle.OnShutdown()
		return
	}

	x.AddGracefulTask(gscore.NewGracefulTask(func(ctx context.Context) {
		err := x.handle.OnRun()
		if err != nil {
			panic(err)
		}
	}))

	go func() {
		<-x.Done()
		x.handle.OnShutdown()
	}()

	x.GracefulExit()
}

func (x *Cmd) InjectHandle(handle gscore.IHandle) {
	if v, ok := handle.(ICmdHandle); ok {
		x.handle = v
		return
	}

	panic("CmdHandle type error")
}
